<?php

namespace Icsoc\ReportForRoleBundle\Model;

use Icsoc\ExportLib\Col;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Icsoc\ExportLib\CsvExport;
use Icsoc\ExportLib\ExcelExport;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

/**
 * Class ReportModel
 *
 * @package Icsoc\ReportForRoleBundle\Model
 */
class ReportModel extends BaseModel
{
    /** @var \Doctrine\DBAL\Connection  */
    protected $container;
    private $conn;
    private $logger;
    private $cdrConn;

    /** @var array */
    private $fixedTitle = array(
        'system' => array(
            'date' => array(
                'text' => 'Date',
                'field' => 'date',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            ),
        ),
        'queue' => array(
            'queue_name' => array(
                'text' => 'Queue Name',
                'field' => 'queue_name',
                'sortable' => true,
                'width' => 120,
                'default_show' => true,
            ),
            'date' => array(
                'text' => 'Date',
                'field' => 'date',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            ),
        ),
        'agent' => array(
            'ag_num' => array(
                'text' => 'Agent Num',
                'field' => 'ag_num',
                'sortable' => true,
                'width' => 100,
                'default_show' => true,
            ),
            'ag_name' => array(
                'text' => 'Agent Name',
                'field' => 'ag_name',
                'sortable' => true,
                'width' => 100,
                'default_show' => true,
            ),
            'date' => array(
                'text' => 'Date',
                'field' => 'date',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            ),
        ),
        'group' => array(
            'group_name' => array(
                'text'=>'Group Name',
                'field'=>'group_name',
                'sortable'=>true,
                'width'=>100,
                'default_show'=> true,
            ),
            'date' => array(
                'text' => 'Date',
                'field' => 'date',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            ),
        ),
    );

    /**
     * 查询数据的表名
     *
     * @var array
     */
    private $types = array(
        'month' => 'rep_%s_month',
        'day' => 'rep_%s_day',
        'hour' => 'rep_%s_hour',
        'halfhour' => 'rep_%s_halfhour',
    );

    /**
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->conn = $this->container->get('doctrine.dbal.default_connection');
        $this->cdrConn = $this->container->get('doctrine.dbal.cdr_connection');
        $this->logger = $this->container->get('logger');
    }

    /**
     *获取报表查询的字段
     *
     * @param $reportType
     * @param $type
     * @param $tableName
     * @param $reportShowType
     * @return array
     */
    public function getFieldsAndGroupBy($reportType, $type, $tableName, $reportShowType)
    {
        $table = $tableName;
        switch ($type) {
            case 'system':
                $field = array('ivr_num', 'in_num', 'lost_num', 'lost_secs', 'lost10_num', 'lost20_num', 'lost25_num',
                    'lost30_num', 'lost35_num', 'lost40_num', 'conn_num', 'queue_secs', 'ring_num', 'ring_secs',
                    'conn5_num', 'conn10_num', 'conn15_num', 'conn20_num', 'conn30_num', 'login_secs', 'conn_secs',
                    'conn_secs', 'wait_secs', 'deal_secs',
                );
                $fields = array();
                foreach ($field as $v) {
                    $fields[] = "SUM($v) AS $v";
                }
                $fields = implode(',', $fields);
                if ($reportType == 'month') {
                    $table = 'rep_system_day';
                    $fields .= ',start_date,nowdate ';
                    $groupBys = ' GROUP BY start_date ';
                } elseif ($reportType == 'hour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_system_hour';
                    $fields .= ',time_stamp,start_date';
                    $groupBys = 'GROUP BY time_stamp';
                } elseif ($reportType == 'halfhour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_system_halfhour';
                    $fields .= ',time_stamp,start_date';
                    $groupBys = 'GROUP BY time_stamp';
                } else {
                    $fields = '*';
                    $groupBys = '';
                }

                return array('fields' => $fields, 'groupBys' => $groupBys, 'tableName' => $table);
                break;
            case 'queue':
                $field = array(
                    'in_num', 'lost_num', 'lost_secs', 'lost10_num', 'lost20_num', 'lost25_num', 'lost30_num',
                    'lost35_num', 'lost40_num', 'conn_num', 'queue_secs', 'ring_num', 'ring_secs', 'conn5_num',
                    'conn10_num', 'conn15_num', 'conn20_num', 'conn30_num', 'conn_secs', 'conn_secs', 'wait_secs',
                    'deal_secs', 'lost1_num', 'lost1_secs', 'lost3_num', 'lost3_secs', 'lost4_num', 'lost4_secs',
                    'lost5_num', 'lost5_secs', 'out_num', 'out_calls', 'out_secs', '`evaluate_-4`', '`evaluate_-3`',
                    '`evaluate_-2`', '`evaluate_-1`', 'evaluate_0', 'evaluate_1', 'evaluate_2', 'evaluate_3', 'evaluate_4',
                    'evaluate_5', 'evaluate_6', 'evaluate_7', 'evaluate_8', 'evaluate_9', 'first_conn_num',
                );

                $fields = array();
                foreach ($field as $v) {
                    $fields[] = "SUM($v) AS $v";
                }

                $fields = implode(',', $fields);
                if ($reportType == 'month') {
                    $table = 'rep_queue_day';
                    $fields .= ',queue_id,queue_name,start_date ';
                    $groupBys = ' GROUP BY start_date,queue_id ';
                } elseif($reportType == 'hour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_queue_hour';
                    $fields .= ',queue_id,queue_name,time_stamp,start_date';
                    $groupBys = ' GROUP BY time_stamp,queue_id';
                } elseif ($reportType == 'halfhour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_queue_halfhour';
                    $fields .= ',queue_id,queue_name,time_stamp,start_date';
                    $groupBys = ' GROUP BY time_stamp,queue_id';
                } else {
                    $fields = '*';
                    $groupBys = '';
                }
                return array('fields' => $fields, 'groupBys' => $groupBys, 'tableName' => $table);
                break;
            case 'group':
                $field = array('in_num', 'out_num', 'out_calls', 'out_secs', 'conn_secs', 'internal_num', 'ring_num', 'ring_secs', 'consult_num', 'consult_secs', 'hold_num', 'hold_secs', 'conference_num',
                    'conference_secs', 'shift_num', 'login_secs', 'ready_secs', 'busy_secs', 'wait_num', 'wait_secs','`evaluate_-4`','`evaluate_-3`','`evaluate_-2`','`evaluate_-1`','evaluate_0','evaluate_1',
                    'evaluate_2','evaluate_3','evaluate_4','evaluate_5','evaluate_6','evaluate_7','evaluate_8','evaluate_9','refuse_num',);
                $fields = array();
                foreach ($field as $v) {
                    $fields[] = "SUM($v) AS $v";
                }
                $fields = implode(',', $fields);
                if ($reportType == 'month') {
                    $table = 'rep_group_day';
                    $fields .= ',group_id,group_name,start_date ';
                    $groupBys = ' GROUP BY start_date,group_id ';
                } elseif ($reportType == 'hour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_group_hour';
                    $fields .= ',group_id,group_name,start_date,time_stamp ';
                    $groupBys = ' GROUP BY time_stamp,group_id ';
                } elseif ($reportType == 'halfhour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_group_halfhour';
                    $fields .= ',group_id,group_name,start_date,time_stamp ';
                    $groupBys = ' GROUP BY time_stamp,group_id ';
                } else {
                    $fields = '*';
                    $groupBys = '';
                }
                return array('fields' => $fields, 'groupBys' => $groupBys, 'tableName' => $table);
                break;
            case 'agent':
                $field = array('in_num','out_num','out_calls','out_secs','conn_secs','internal_num','ring_num',
                    'ring_secs','consult_num','consult_secs','hold_num','hold_secs','conference_num','conference_secs',
                    'shift_num','login_secs','ready_secs','busy_secs','wait_num','wait_secs','`evaluate_-4`','`evaluate_-3`','`evaluate_-2`','`evaluate_-1`','evaluate_0','evaluate_1',
                    'evaluate_2','evaluate_3','evaluate_4','evaluate_5','evaluate_6','evaluate_7','evaluate_8','evaluate_9','refuse_num',
                );
                $fields = array();
                foreach ($field as $v) {
                    $fields[] = "SUM($v) AS $v";
                }
                $fields = implode(',', $fields);
                if ($reportType == 'month') {
                    $table = 'rep_agent_day';
                    $fields .= ',ag_id,ag_num,ag_name,start_date ';
                    $groupBys = ' GROUP BY start_date,ag_id ';
                } elseif ($reportType == 'hour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_agent_hour';
                    $fields .= ',ag_id,ag_num,ag_name,start_date,time_stamp ';
                    $groupBys = ' GROUP BY time_stamp,ag_id ';
                } elseif ($reportType == 'halfhour' && !empty($reportShowType) && $reportShowType == 2) {
                    $table = 'rep_agent_halfhour';
                    $fields .= ',ag_id,ag_num,ag_name,start_date,time_stamp ';
                    $groupBys = ' GROUP BY time_stamp,ag_id ';
                } else {
                    $fields = '*';
                    $groupBys = '';
                }
                return array('fields' => $fields, 'groupBys' => $groupBys, 'tableName' => $table);
                break;
        }
    }

    /**
     * 获取数据
     * @param array $param
     * @return array|int
     */
    public function getData(array $param = array())
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $infos = empty($param['info']) ? '' : $param['info'];
        $repType = empty($param['rep_type']) ? 'month' : $param['rep_type'];
        $type = empty($param['type']) ? 'system' : $param['type'];
        $roleId = empty($param['roleId']) ? 0 : $param['roleId'];
        $reportShowType = empty($param['report_show_type']) ? '' : $param['report_show_type'];
        $reg = "/^[1-9]\d{3}-(0[1-9]|1[0-2])$/"; //2015-05 格式判断

        /** @var array $msg  验证vcc_code是否正确 */
        $msg = $vccId = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //分页搜索相关信息；
        $info = array();
        if (!empty($infos)) {
            $info = json_decode($infos, true);
            if (json_last_error()) {
                return array('code' => 403, 'message' => 'info格式非json');
            }
        }

        if (!isset($this->types[$repType])) {
            return array('code' => 404, 'message' => 'type格式不正确');
        }
        $tableName = sprintf($this->types[$repType], $type);
        $where = 'vcc_id = :vcc_id';
        $condition = array('vcc_id' => $vccId);
        $agStaCondition['condition'] = '';

        $column = 'start_date';
        $sqlItems = $this->getFieldsAndGroupBy($repType, $type, $tableName, $reportShowType);
        $tableName = $sqlItems['tableName'];
        $fields = $sqlItems['fields'];
        $groupBy = $sqlItems['groupBys'];

        $tmpStartTime = $info['filter']['start_date'];
        $tmpEndTime = $info['filter']['end_date'];
        //月报表的时间，没有日
        if (strlen($info['filter']['start_date']) < 10) {
            $tmpStartTime = $info['filter']['start_date'].'-01';
        }
        if (strlen($info['filter']['end_date']) < 10) {
            $firstday = date('Y-m-01', strtotime($info['filter']['end_date'].'-01'));
            $lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));
            $tmpEndTime = $lastday;
        }
        $time = $this->container->get("icsoc_core.common.class")->rolesCanSearchAllReportDatas($tmpStartTime.' 00:00:00', $tmpEndTime.' 23:59:59', 'date');
        if ($time == 'no') {
            $where .= ' AND id  = -1';
        }
        if (isset($info['filter'])) {
            //开始时间
            if (isset($info['filter']['start_date']) && !empty($info['filter']['start_date'])) {
                $startDate = $info['filter']['start_date'];
                if (isset($time['startTime'])) {
                    $startDate = $time['startTime'];
                }
                switch ($repType) {
                    case 'month':
                        //$msg = $this->container->get('icsoc_data.helper')->regexRormat($reg, $startDate, '开始日期不正确', 404);
                        if (strlen($startDate) < 10) {
                            $startDate .= "-01";
                        }
                        $column = 'nowdate';
                        break;
                    case 'day':
                        $column = 'nowdate';
                        break;
                    case 'hour':
                    case 'halfhour':
                        //$msg = $this->container->get('icsoc_data.helper')->isDate('开始日期不正确', $startDate, 404);
                        break;
                }

                if (!empty($msg) && is_array($msg)) {
                    return $msg;
                }

                $where .= " AND ".$column." >= :start_date ";
                $condition['start_date'] = $startDate;
                $agStaCondition['condition'] .= ' AND start_time >= '.strtotime($startDate);
            }
            //结束时间
            if (isset($info['filter']['end_date']) && !empty($info['filter']['end_date'])) {
                $endDate = $info['filter']['end_date'];
                if (isset($time['endTime'])) {
                    $endDate = $time['endTime'];
                }
                switch ($repType) {
                    case 'month':
                        //$msg = $this->container->get('icsoc_data.helper')->regexRormat($reg, $endDate, '开始日期不正确', 405);
                        if (strlen($endDate) < 10) {
                            $endDate = $endDate.'-01 23:59:59';
                        }
                        break;
                    case 'day':
                        $column = 'nowdate';
                        break;
                    case 'hour':
                    case 'halfhour':
                        //$msg = $this->container->get('icsoc_data.helper')->isDate('开始日期不正确', $endDate, 405);
                        break;
                }
                if (!empty($msg) && is_array($msg)) {
                    return $msg;
                }

                $where .= " AND ".$column." <= :end_date ";
                $condition['end_date'] = $endDate;
                $agStaCondition['condition'] .= ' AND start_time <= '.strtotime($endDate);
            }

            //权限
            if (isset($info['filter']['data_id'])) {
                $dataIds = $info['filter']['data_id'];
                if (empty($dataIds)) {
                    $dataIds = -1;
                }
                switch ($type) {
                    case 'system':
                        break;
                    case 'group':
                        $where .= ' AND group_id in ('.$dataIds.')';
                        $agStaCondition['condition'] .= ' AND group_id in ('.$dataIds.')';
                        break;
                    case 'queue':
                        $where .= ' AND queue_id in ('.$dataIds.')';
                        break;
                    case 'agent':
                        $where .= ' AND ag_id in ('.$dataIds.')';
                        break;
                }
            }
        }

        $total = $this->cdrConn->fetchColumn(
            'SELECT count(*) '.
            ' FROM '.$tableName.
            ' WHERE '.$where,
            $condition
        );
        if (($reportShowType == 2 && ($repType == 'hour' || $repType == 'halfhour')) || $repType == 'month') {
            $total = $this->cdrConn->fetchAll(
                'SELECT * '.
                ' FROM '.$tableName.
                ' WHERE '.$where.$groupBy,
                $condition
            );

            $total = count($total);
        }
        $page = $this->container->get("icsoc_data.helper")->getPageInfoExt($total, $tableName, $info);
        if (empty($info['export'])) {
            $limit = ($page['limit'] == -1) ? ' LIMIT 0,3000 ' : ' LIMIT '.$page['start'].','.$page['limit'];
            $result = $this->cdrConn->fetchAll(
                'SELECT '.$fields.
                ' FROM '.$tableName.
                ' WHERE '.$where.$groupBy.
                ' ORDER BY '.$page['sort'].
                $limit,
                $condition
            );
        } else {
            $result = $this->cdrConn->fetchAll(
                'SELECT '.$fields.
                ' FROM '.$tableName.
                ' WHERE '.$where.$groupBy.
                ' ORDER BY '.$page['sort'],
                $condition
            );
        };
        $data = array();

        foreach ($result as $key => $v) {
            $data[$key] = $v;
            if ($repType == 'day') {
                $data[$key]['date'] = $v['nowdate'];
            } else {
                if ($reportShowType == 2) {
                    $data[$key]['date'] = $v['time_stamp'];
                } else {
                    $data[$key]['date'] = $v['start_date'];
                }
            }

        }

        if ($type == 'group' && $repType != 'halfhour') {
            /** @var  $agentStaReason (坐席状态原因) */
            $agStaReason = $this->container->get('icsoc_data.model.report')->getAgentStaReason($vccId);
            $agStaCondition['vcc_id'] = $vccId;
            /** @var  $agStaDetail (业务组状态明细) */
            $agStaDetail = $this->container->get('icsoc_data.model.report')->getGroupStaDetail($agStaCondition);
            $data = $this->addAgstaReasonToResult($result, $agStaReason, $agStaDetail, $type, $repType, $reportShowType);
        }

        if ($type == 'agent' && $repType != 'halfhour') {
            /** @var  $agentStaReason (坐席状态原因) */
            $agStaReason = $this->container->get('icsoc_data.model.report')->getAgentStaReason($vccId);
            $agStaCondition['vcc_id'] = $vccId;
            $agStaCondition['type'] = $repType;
            $agStaCondition['reason'] = $agStaReason;
            /** @var  $agStaDetail (坐席状态明细) */
            $agStaDetail = $this->container->get('icsoc_data.model.report')->getAgentStaDetail($agStaCondition);
            $data = $this->addAgstaReasonToResult($result, $agStaReason, $agStaDetail, $type, $repType, $reportShowType);
        }

        $data = $this->processData($data, $vccId, $repType, $type, $roleId, $reportShowType);

        return array(
            'code' => 200,
            'total' => $page['totalPage'],
            'page' => $page['page'],
            'records' => $total,
            'rows' => $data['data'],
            'footer' => $data['footer'],
        );
    }

    /**
     * 数据报表导出文件
     * @param array $param
     * @return array|int
     */
    public function getExportFile(array $param = array())
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $infos = empty($param['info']) ? '' : $param['info'];
        $repType = empty($param['rep_type']) ? 'month' : $param['rep_type'];
        $type = empty($param['type']) ? 'system' : $param['type'];
        $roleId = empty($param['roleId']) ? 0 : $param['roleId'];
        $reportShowType = empty($param['report_show_type']) ? '' : $param['report_show_type'];
        $reg = "/^[1-9]\d{3}-(0[1-9]|1[0-2])$/"; //2015-05 格式判断

        /** @var array $msg  验证vcc_code是否正确 */
        $msg = $vccId = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //分页搜索相关信息；
        $info = array();
        if (!empty($infos)) {
            $info = json_decode($infos, true);
            if (json_last_error()) {
                return array('code' => 403, 'message' => 'info格式非json');
            }
        }

        if (!isset($this->types[$repType])) {
            return array('code' => 404, 'message' => 'type格式不正确');
        }
        $tableName = sprintf($this->types[$repType], $type);
        $where = 'vcc_id = :vcc_id';
        $condition = array('vcc_id' => $vccId);
        $agStaCondition['condition'] = '';

        $column = 'start_date';
        $sqlItems = $this->getFieldsAndGroupBy($repType, $type, $tableName, $reportShowType);
        $tableName = $sqlItems['tableName'];
        $fields = $sqlItems['fields'];
        $groupBy = $sqlItems['groupBys'];

        $tmpStartTime = $info['filter']['start_date'];
        $tmpEndTime = $info['filter']['end_date'];
        //月报表的时间，没有日
        if (strlen($info['filter']['start_date']) < 10) {
            $tmpStartTime = $info['filter']['start_date'].'-01';
        }
        if (strlen($info['filter']['end_date']) < 10) {
            $firstday = date('Y-m-01', strtotime($info['filter']['end_date'].'-01'));
            $lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));
            $tmpEndTime = $lastday;
        }
        $time = $this->container->get("icsoc_core.common.class")->rolesCanSearchAllReportDatas($tmpStartTime.' 00:00:00', $tmpEndTime.' 23:59:59', 'date');
        if ($time == 'no') {
            $where .= ' AND id  = -1';
        }
        if (isset($info['filter'])) {
            //开始时间
            if (isset($info['filter']['start_date']) && !empty($info['filter']['start_date'])) {
                $startDate = $info['filter']['start_date'];
                if (isset($time['startTime'])) {
                    $startDate = $time['startTime'];
                }
                switch ($repType) {
                    case 'month':
                        //$msg = $this->container->get('icsoc_data.helper')->regexRormat($reg, $startDate, '开始日期不正确', 404);
                        if (strlen($startDate) < 10) {
                            $startDate .= "-01";
                        }
                        $column = 'nowdate';
                        break;
                    case 'day':
                        $column = 'nowdate';
                        break;
                    case 'hour':
                    case 'halfhour':
                        //$msg = $this->container->get('icsoc_data.helper')->isDate('开始日期不正确', $startDate, 404);
                        break;
                }

                if (!empty($msg) && is_array($msg)) {
                    return $msg;
                }

                $where .= " AND ".$column." >= :start_date ";
                $condition['start_date'] = $startDate;
                $agStaCondition['condition'] .= ' AND start_time >= '.strtotime($startDate);
            }
            //结束时间
            if (isset($info['filter']['end_date']) && !empty($info['filter']['end_date'])) {
                $endDate = $info['filter']['end_date'];
                if (isset($time['endTime'])) {
                    $endDate = $time['endTime'];
                }
                switch ($repType) {
                    case 'month':
                        //$msg = $this->container->get('icsoc_data.helper')->regexRormat($reg, $endDate, '开始日期不正确', 405);
                        if (strlen($endDate) < 10) {
                            $endDate = $endDate.'-01 23:59:59';
                        }
                        break;
                    case 'day':
                        $column = 'nowdate';
                        break;
                    case 'hour':
                    case 'halfhour':
                        //$msg = $this->container->get('icsoc_data.helper')->isDate('开始日期不正确', $endDate, 405);
                        break;
                }
                if (!empty($msg) && is_array($msg)) {
                    return $msg;
                }

                $where .= " AND ".$column." <= :end_date ";
                $condition['end_date'] = $endDate;
                $agStaCondition['condition'] .= ' AND start_time <= '.strtotime($endDate);
            }

            //权限
            if (isset($info['filter']['data_id'])) {
                $dataIds = $info['filter']['data_id'];
                if (empty($dataIds)) {
                    $dataIds = -1;
                }
                switch ($type) {
                    case 'system':
                        break;
                    case 'group':
                        $where .= ' AND group_id in ('.$dataIds.')';
                        $agStaCondition['condition'] .= ' AND group_id in ('.$dataIds.')';
                        break;
                    case 'queue':
                        $where .= ' AND queue_id in ('.$dataIds.')';
                        break;
                    case 'agent':
                        $where .= ' AND ag_id in ('.$dataIds.')';
                        break;
                }
            }
        }

        $total = $this->cdrConn->fetchColumn(
            'SELECT count(*) '.
            ' FROM '.$tableName.
            ' WHERE '.$where,
            $condition
        );
        if (($reportShowType == 2 && ($repType == 'hour' || $repType == 'halfhour')) || $repType == 'month') {
            $total = $this->cdrConn->fetchAll(
                'SELECT * '.
                ' FROM '.$tableName.
                ' WHERE '.$where.$groupBy,
                $condition
            );

            $total = count($total);
        }
        $rst = $this->getTitleReport(
            array('report_name' => $type, 'report_type' => $repType, 'roleId' => $roleId)
        );
        $title = array();
        if (isset($rst['code']) && $rst['code'] == 200) {
            $title = $rst['data'];
        }
        $titleItem = array();
        $translator = $this->container->get('translator');
        foreach ($title as $key => $v) {
            $titleItem[$v['field']] = array(
                'title' => $translator->trans($v['text']),
                'type' => Col::TYPE_STRING,
            );
        }
        $tmp = $this->container->getParameter('export_dir');
        switch ($info['export']) {
            case 'csv':
                $export = new CsvExport(array('tmp' => $tmp));
                $export->setCols($titleItem);
                break;
            case 'excel':
                $export = new ExcelExport(array('tmp' => $tmp));
                $export->setCols($titleItem);
                break;
            default:
                exit;
        }
        $page = $this->container->get("icsoc_data.helper")->getPageInfoExt($total, $tableName, $info);
        $footerData = array();
        for ($i = 1; $i <= ceil($total/10000); $i++) {
            $start = $i * 10000 - 10000;
            $result = $this->cdrConn->fetchAll(
                'SELECT '.$fields.' FROM '.$tableName.
                ' WHERE '.$where.$groupBy.
                ' ORDER BY '.$page['sort'].
                ' limit '.$start.',10000',
                $condition
            );
            $data = array();
            foreach ($result as $key => $v) {
                $data[$key] = $v;
                if ($repType == 'day') {
                    $data[$key]['date'] = $v['nowdate'];
                } else {
                    if ($reportShowType == 2) {
                        $data[$key]['date'] = $v['time_stamp'];
                    } else {
                        $data[$key]['date'] = $v['start_date'];
                    }
                }
            }
            if ($type == 'group' && $repType != 'halfhour') {
                /** @var  $agentStaReason (坐席状态原因) */
                $agStaReason = $this->container->get('icsoc_data.model.report')->getAgentStaReason($vccId);
                $agStaCondition['vcc_id'] = $vccId;
                /** @var  $agStaDetail (业务组状态明细) */
                $agStaDetail = $this->container->get('icsoc_data.model.report')->getGroupStaDetail($agStaCondition);
                $data = $this->addAgstaReasonToResult($result, $agStaReason, $agStaDetail, $type, $repType, $reportShowType);
            }
            if ($type == 'agent' && $repType != 'halfhour') {
                /** @var  $agentStaReason (坐席状态原因) */
                $agStaReason = $this->container->get('icsoc_data.model.report')->getAgentStaReason($vccId);
                $agStaCondition['vcc_id'] = $vccId;
                $agStaCondition['type'] = $repType;
                $agStaCondition['reason'] = $agStaReason;
                /** @var  $agStaDetail (坐席状态明细) */
                $agStaDetail = $this->container->get('icsoc_data.model.report')->getAgentStaDetail($agStaCondition);
                $data = $this->addAgstaReasonToResult($result, $agStaReason, $agStaDetail, $type, $repType, $reportShowType);
            }
            $allData = $this->processData($data, $vccId, $repType, $type, $roleId, $reportShowType);
            if (!empty($allData['data'])) {
                foreach ($allData['data'] as $k => $v) {
                    $columns = array();
                    foreach ($titleItem as $title => $name) {
                        $columns[$title] = isset($v[$title]) ? $v[$title] : '';
                    }
                    $export->writeRow($columns);
                }
            } else {
                $export->writeRow(array());
            }
            $footerData[] = $allData['footer'];
        }
        $footerData = $this->processData($footerData, $vccId, $repType, $type, $roleId, $reportShowType, true);
        $columns = array();
        foreach ($titleItem as $title => $name) {
            $columns[$title] = isset($footerData['footer'][$title]) ? $footerData['footer'][$title] : '';
        }
        $export->writeRow($columns);
        $fileName = $export->build();
        switch ($info['export']) {
            case 'csv':
                $tmpName = $tmp.'/Data'.date('YmdHis').'.zip';
                break;
            case 'excel':
                $tmpName = $tmp.'/Data'.date('YmdHis').'.xlsx';
                break;
            default:
                exit;
        }
        copy($fileName, $tmpName);
        $response = new BinaryFileResponse($tmpName);
        $response->setContentDisposition('attachment', basename($tmpName));
        $response->deleteFileAfterSend(true);

        return $response;
    }

    /**
     * 添加坐席状态原因到结果数据中
     *
     * @param $result
     * @param $agStaReason
     * @param $agStaDetail
     * @param $reportName
     * @param $reportType
     * @return array
     */
    public function addAgstaReasonToResult($result, $agStaReason, $agStaDetail, $reportName, $reportType, $reportShowType)
    {
        $data = array();
        if ($reportName == 'group' && $reportType != 'halfhour') {
            foreach ($result as $key => $v) {
                foreach ($agStaReason as $k => $value) {
                    if (!isset($v['agstanum'.$k])) {
                        $v['agstanum'.$k] = 0;
                    }

                    if (!isset($v['agstaduration'.$k])) {
                        $v['agstaduration'.$k] = 0;
                    }
                }
                $v['agstanum_other'] = 0;
                $v['agstaduration_other'] = 0;

                foreach ($agStaDetail as $val) {
                    $startMonth = sprintf('%02d', $val['start_month']);
                    $startDay = sprintf('%02d', $val['start_day']);
                    $startHour = sprintf('%02d', $val['start_hour']);
                    if ($reportType == 'day') {
                        $compareDate = $v['nowdate'];
                        $agStaDate = $val['start_year'].'-'.$startMonth.'-'.$startDay;
                    } else if ($reportType == 'hour'){
                        $compareDate = $v['start_date'].'-'.$v['time_stamp'];
                        $agStaDate = $val['start_year'].'-'.$startMonth.'-'.$startDay.'-'.$startHour;
                    } else if ($reportType == 'month') {
                        $compareDate = $v['start_date'];
                        $agStaDate = $val['start_year'].'-'.$startMonth;
                    }

                    if ($reportShowType == 2) {
                        if ($v['time_stamp'] == $startHour && $val['group_id'] == $v['group_id'] && $val['ag_sta_type'] == 2) {
                            if (isset($v['agstanum'.$val['ag_sta_reason']]) && in_array($val['ag_sta_reason'], array_keys($agStaReason))) {
                                $v['agstanum'.$val['ag_sta_reason']] += $val['num'];
                            } else {
                                $v['agstanum_other'] += $val['num'];
                            }
                            if (isset($v['agstaduration'.$val['ag_sta_reason']]) && in_array($val['ag_sta_reason'], array_keys($agStaReason))) {
                                $v['agstaduration'.$val['ag_sta_reason']] += $val['duration'];
                            } else {
                                $v['agstaduration_other'] += $val['duration'];
                            }
                        }
                    } else {
                        if ($compareDate == $agStaDate && $val['group_id'] == $v['group_id'] && $val['ag_sta_type'] == 2) {
                            if (isset($v['agstanum'.$val['ag_sta_reason']]) && in_array($val['ag_sta_reason'], array_keys($agStaReason))) {
                                $v['agstanum'.$val['ag_sta_reason']] += $val['num'];
                            } else {
                                $v['agstanum_other'] += $val['num'];
                            }
                            if (isset($v['agstaduration'.$val['ag_sta_reason']]) && in_array($val['ag_sta_reason'], array_keys($agStaReason))) {
                                $v['agstaduration'.$val['ag_sta_reason']] += $val['duration'];
                            } else {
                                $v['agstaduration_other'] += $val['duration'];
                            }
                        }
                    }
                }

                $data[$key] = $v;
                $data[$key]['date'] = $compareDate;

            }
        }

        if ($reportName == 'agent' && $reportType != 'halfhour') {
            if ($reportShowType == 2) {
                foreach ($result as $key => $v) {
                    foreach ($agStaReason as $reasonId => $reasonName) {
                        $v['agstanum'.$reasonId] = 0;
                        $v['agstaduration'.$reasonId] = 0;
                        $v['agstanum_other'] = 0;
                        $v['agstaduration_other'] = 0;

                        foreach ($agStaDetail as $agDate => $agData) {
                            $timeStamp = substr($agDate,strrpos($agDate,' ')+1);//获取时间中的小时
                            if ($v['time_stamp'] == $timeStamp) {
                                if (isset($agData[$v['ag_id']][$reasonId])) {
                                    $v['agstanum'.$reasonId] += $agData[$v['ag_id']][$reasonId]['num'];
                                    $v['agstaduration'.$reasonId] += $agData[$v['ag_id']][$reasonId]['secs'];
                                }

                                $agNumOther = isset($agData[$v['ag_id']]['other']['num']) ? $agData[$v['ag_id']]['other']['num'] : 0;
                                $agsDurationOther = isset($agData[$v['ag_id']]['other']['secs']) ? $agData[$v['ag_id']]['other']['secs'] : 0;
                                $v['agstanum_other'] += $agNumOther;
                                $v['agstaduration_other'] += $agsDurationOther;

                            }
                        }
                    }

                    $data[$key] = $v;
                    $data[$key]['date'] = $v['time_stamp'];
                }
            } else {
                foreach ($result as $key => $v) {
                    switch ($reportType) {
                        case 'halfhour':
                            break;
                        case 'hour':
                            $compareDate = $v['start_date'].' '.$v['time_stamp'];
                            break;
                        case 'day':
                            $compareDate = $v['nowdate'];
                            break;
                        case 'month':
                            $compareDate = $v['start_date'];
                            break;
                    }
                    foreach ($agStaReason as $reasonId => $reasonName) {
                        $v['agstanum'.$reasonId] = 0;
                        $v['agstaduration'.$reasonId] = 0;

                        if (isset($agStaDetail[$compareDate][$v['ag_id']][$reasonId]['num'])) {
                            $v['agstanum'.$reasonId] = $agStaDetail[$compareDate][$v['ag_id']][$reasonId]['num'];
                        }

                        if (isset($agStaDetail[$compareDate][$v['ag_id']][$reasonId]['secs'])) {
                            $v['agstaduration'.$reasonId] = $agStaDetail[$compareDate][$v['ag_id']][$reasonId]['secs'];
                        }
                    }
                    $v['agstanum_other'] = isset($agStaDetail[$compareDate][$v['ag_id']]['other']['num']) ?
                        $agStaDetail[$compareDate][$v['ag_id']]['other']['num'] : 0;
                    $v['agstaduration_other'] = isset($agStaDetail[$compareDate][$v['ag_id']]['other']['secs']) ?
                        $agStaDetail[$compareDate][$v['ag_id']]['other']['secs'] : 0;

                    $data[$key] = $v;
                    $data[$key]['date'] = $compareDate;
                }
            }
        }

        return $data;
    }

    /**
     * @param array $param
     * @return array
     */
    public function getTitleReport($param)
    {
        $title = array();
        $reportName = isset($param['report_name']) ? $param['report_name'] : '';
        $reportType = isset($param['report_type']) ? $param['report_type'] : '';
        $roleId = isset($param['roleId']) ? $param['roleId'] : '';
        $param['roleId'] = $roleId;
        if (empty($reportName)) {
            return array('code'=>401, 'message'=>'报表名称不能为空');
        }
        if (($reportName == 'agent' || $reportName == 'group') && empty($reportType)) {
            return array('code'=>402, 'message'=>'报表类型不能为空');
        }
        $param['data_type'] = 'title';
        $rst = $this->processConfig($param);
        if (isset($rst['code']) && $rst['code'] == 200) {
            $title = $rst['data'];
        }
        $title = array_merge($this->fixedTitle[$reportName], $title);

        return array('code'=>200, 'message'=>'success', 'data'=>$title);
    }

    /**
     * @param array $param
     * @return array
     */
    private function getDataReport($param)
    {
        $title = array();
        $count = array();
        $allTitles = array();
        $data = isset($param['data']) ? $param['data'] : array();
        $reportName = isset($param['report_name']) ? $param['report_name'] : '';
        $workTime = isset($param['work_time']) ? $param['work_time'] : '';
        $repType = isset($param['rep_type']) ? $param['rep_type'] : '';
        $roleId = isset($param['roleId']) ? $param['roleId'] : '';
        $reportShowType = isset($param['reportShowType']) ? $param['reportShowType'] : '';
        $isFooter = isset($param['footer']) ? $param['footer'] : false;

        if (empty($data)) {
            return array('code'=>401, 'message'=>'数据不能为空');
        }
        if (empty($reportName)) {
            return array('code'=>402, 'message'=>'报表名称不能为空');
        }
        if ($reportName == 'system' && empty($workTime)) {
            return array('code'=>403, 'message'=>'workTime不能为空');
        }
        $param['data_type'] = 'data';
        $param['roleId'] = $roleId;
        $rst = $this->processConfig($param);

        if (isset($rst['code']) && $rst['code'] == 200) {
            $title = $rst['data']['title'];
            $count = $rst['data']['count'];
            $allTitles = $rst['data']['allTitles'];
        }
        /** 过滤计算项(去掉分子分母都为空的情况)*/
        $count = $this->filterCalculateItems($count);

        $gridData = array();
        $footer = array();//统计用
        $tmpFooter = array();
        foreach ($data as $key => $value) {
            if ($reportName == 'system' || $reportName == 'group') {
                if (!$isFooter) {
                    $value['agents'] = ceil($value['login_secs'] / $workTime);
                }
            }

            $value = $this->proccessValue($value, $reportName);
            //处理footer
            foreach ($value as $k => $v) {
                if (!in_array($k, array('id','vcc_id','time_stamp','ag_name','ag_num', 'queue_name', 'group_name'))) {
                    if (is_numeric($v)) {
                        $footer[$k] = isset($footer[$k]) ? $footer[$k] + $v : $v;
                    }
                }
            }
            $value = $this->addCalculationField($value, $count, $title, $reportName, $allTitles);//添加计算字段,allTitles用来计算x秒接通率，当分子分母没有被选中时用
            if (!$isFooter) {
                $value['date'] = $this->processDate($value, $repType, $reportShowType);//处理日期字段；
            }
            $gridData[$key] = $value;

            /** 所有的值相加得到tmpfooter的值,但是此时需要计算的值是不准确的*/
            foreach ($value as $k => $v) {
                if (!in_array($k, array('id','vcc_id','time_stamp','ag_name','ag_num', 'queue_name', 'group_name'))) {
                    if (is_numeric($v)) {
                        $tmpFooter[$k] = isset($tmpFooter[$k]) ? $tmpFooter[$k] + $v : $v;
                    } else {
                        $tmpFooter[$k] = $v;
                    }
                }
            }
        }

        $footer = $this->addCalculationField($footer, $count, $title, $reportName, $allTitles);
        $footerRes = array();
        /** 如果是需要计算的值，则取$footer里的值，$tmpFooter里的值不准确*/
        foreach ($tmpFooter as $column => $val) {
            $footerRes[$column] = $val;
            foreach ($count as $item => $itemConfig) {
                if (isset($allTitles[$item]) && $allTitles[$item]['field'] == $column) {
                    $footerRes[$column] = $footer[$column];
                }
            }
        }
        $footerRes['date'] = $this->container->get("translator")->trans("Total"); //把footer的日期变成合计；

        return array('code' => 200, 'message' => 'success', 'data' => $gridData, 'footer' => $footerRes);
    }

    /**
     *过滤需要计算的字段
     *
     * @param $calculateItems
     * @return mixed
     */
    public function filterCalculateItems($calculateItems)
    {
        foreach ($calculateItems as $item => $config) {
            if (!isset($config['numerator']) && !isset($config['denominator'])) {
                unset($calculateItems[$item]);
            }

            if ((empty($config['numerator']['plus']) && empty($config['numerator']['minus']) && (isset($config['numerator']['multiply']) && empty($config['numerator']['multiply']['plus']) && empty($config['numerator']['multiply']['minus']))))
            {
                if ((empty($config['denominator']['plus']) && empty($config['denominator']['minus']) && (isset($config['denominator']['multiply']) && empty($config['denominator']['multiply']['plus']) && empty($config['denominator']['multiply']['minus'])))) {
                    unset($calculateItems[$item]);
                }
            }
        }

        return $calculateItems;
    }

    /**
     *从cc_roles表中获取报表的配置信息
     *@param string $reportName 报表名称(system,group,agent,queue)
     *@param string $roleId 角色Id
     *@param string $type  (fixed:数据报表，custom:自定义报表)
     *@return array array('configs' =>
     *                       array('system' => array(
     *                        'ivrInboundNum'=>array(
     *                            'text'=>'Ivr呼入',
     *                            'field'=>'ivr_num',
     *                            'sortable'=>true,
     *                            'width'=>60,
     *                            'default_show'=> true),
     *                       ...
     *                     )),
     *                  'calculateItems' = > $calculates
     *   )
     */
    public function getReportConfig($reportName, $roleId, $type, $reportType)
    {
        $user = $this->container->get('security.token_storage')->getToken()->getUser();
        $vccId = $user->getVccId();
        $config = $this->conn->fetchAll("select report_config from cc_roles where role_id = :role_id and vcc_id = :vcc_id",
            array('role_id' => $roleId,'vcc_id' => $vccId));
        /** 从全局配置中获取显示值*/
        $globalConfig = $this->conn->fetchAll("select report_config from cc_global_report_config where vcc_id = :vcc_id",
            array('vcc_id' => $vccId));

        if (!empty($config[0]['report_config'])) {
            $config = json_decode($config[0]['report_config'], true);
            $reportItems = $config[$reportName][$type];
            $calculateItems = $config[$reportName]['calculateItems'];
            $showValues = array();
            if (isset($config[$reportName]['showValues']) && !empty($config[$reportName]['showValues'])) {
                $showValues = $config[$reportName]['showValues'][$type];
            }

            $reportConfigs = array();
            $newItems = array();
            if (!empty($reportItems)) {
                if (!empty($showValues)) {
                    foreach ($reportItems as $k => $item) {
                        if (in_array($item, array_keys($this->reportItems[$reportName][$type.'_report']))) {
                            $newItems[$item]['width'] = $this->reportItems[$reportName][$type.'_report'][$item]['width'];
                            $newItems[$item]['field'] = $this->reportItems[$reportName][$type.'_report'][$item]['field'];
                        } else {
                            $newItems[$item]['width'] = 100;
                            $newItems[$item]['field'] = $item;
                        }
                        $newItems[$item]['name'] = isset($showValues[$item]['name']) ? $showValues[$item]['name'] : $this->reportItems[$reportName][$type.'_report'][$item]['text'];
                        $newItems[$item]['sort'] = isset($showValues[$item]['sort']) ? $showValues[$item]['sort'] : 100;
                    }
                } else {
                    //报表配置为原来的旧数据格式,不参与其它的配置处理，直接返回选中的配置项
                    $defaultTitle = $this->reportItems[$reportName][$type.'_report'];
                    $defaultCount = $this->calculateItems[$reportName];

                    switch ($reportName) {
                        case 'system':
                            $connect = array(5, 10, 15, 20, 30);
                            $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect);
                            $defaultTitle = $res['title'];
                            $defaultCount = $res['count'];
                        case 'queue':
                            $connect = array(5, 10, 15, 20, 30);
                            $waive = array(10, 20, 25, 30,35, 40);
                            $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect, $waive);
                            $defaultTitle = $res['title'];
                            $defaultCount = $res['count'];
                            break;
                        case 'agent':
                        case 'group':
                            $defaultTitle = $this->proccessStaReason($defaultTitle, $reportType);
                            break;
                    }

                    foreach ($defaultTitle as $k => $item) {
                        if (!in_array($k, $reportItems)) {
                            unset($defaultTitle[$k]);
                        }
                    }

                    return array('configs' => $defaultTitle, 'calculateItems' => $defaultCount);
                }

            } else {
                if (!empty($showValues)) {
                    foreach ($showValues as $item => $itemShowValue) {
                        if (in_array($item, array_keys($this->reportItems[$reportName][$type.'_report']))) {
                            $newItems[$item]['width'] = $this->reportItems[$reportName][$type.'_report'][$item]['width'];
                            $newItems[$item]['field'] = $this->reportItems[$reportName][$type.'_report'][$item]['field'];
                        } else {
                            $newItems[$item]['width'] = 100;
                            $newItems[$item]['field'] = $item;
                        }
                        $newItems[$item]['name'] = isset($showValues[$item]['name']) ? $showValues[$item]['name'] : $item;
                        $newItems[$item]['sort'] = isset($showValues[$item]['sort']) ? $showValues[$item]['sort'] : 100;
                    }

                } else {//报表的配置还是原来的数据格式并且没有选中任何配置时，则显示所有字段。
                    $defaultTitle = $this->reportItems[$reportName][$type.'_report'];
                    $defaultCount = $this->calculateItems[$reportName];

                    switch ($reportName) {
                        case 'system':
                            $connect = array(5, 10, 15, 20, 30);
                            $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect);
                            $defaultTitle = $res['title'];
                            $defaultCount = $res['count'];
                        case 'queue':
                            $connect = array(5, 10, 15, 20, 30);
                            $waive = array(10, 20, 25, 30, 35, 40);
                            $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect, $waive);
                            $defaultTitle = $res['title'];
                            $defaultCount = $res['count'];
                            break;
                        case 'agent':
                        case 'group':
                            $defaultTitle = $this->proccessStaReason($defaultTitle, $reportType);
                            break;
                    }

                    return array('configs' => $defaultTitle, 'calculateItems' => $defaultCount);
                }
            }
        } else {//如果角色配置为空，那么报表字段显示所有的配置
            $defaultTitle = $this->reportItems[$reportName][$type.'_report'];
            $defaultCount = $this->calculateItems[$reportName];

            switch ($reportName) {
                case 'system':
                    $connect = array(5, 10, 15, 20, 30);
                    $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect);
                    $defaultTitle = $res['title'];
                    $defaultCount = $res['count'];
                case 'queue':
                    $connect = array(5, 10, 15, 20, 30);
                    $waive = array(10, 20, 25, 30,35, 40);
                    $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect, $waive);
                    $defaultTitle = $res['title'];
                    $defaultCount = $res['count'];
                    break;
                case 'agent':
                case 'group':
                    $defaultTitle = $this->proccessStaReason($defaultTitle, $reportType);
                    break;
            }

            if (!empty($globalConfig[0]['report_config'])) {
                $globalConfig = json_decode($globalConfig[0]['report_config'], true);
                $showValues = $globalConfig[$reportName]['showValues'][$type];
                $newItems = array();
                foreach ($globalConfig[$reportName][$type] as $defaultItem) {
                    if ($showValues[$defaultItem]['globalConfig'] == 1) {
                        $newItems[$defaultItem] = array(
                            'text' => isset($showValues[$defaultItem]['name']) ? $showValues[$defaultItem]['name'] : $defaultTitle[$defaultItem]['text'],
                            'field' => isset($this->reportItems[$reportName][$type.'_report'][$defaultItem]['field']) ? $this->reportItems[$reportName][$type.'_report'][$defaultItem]['field'] : $defaultItem ,
                            'sortable' => false,
                            'width' => isset($defaultTitle[$defaultItem]['width']) ? $defaultTitle[$defaultItem]['width'] : 100,
                            'default_show' => true,
                        );
                    }
                }
                $defaultTitle = array_merge($defaultTitle, $newItems);
                $defaultCount = array_merge($defaultCount, $globalConfig[$reportName]['calculateItems']);
            }

            return array('configs' => $defaultTitle, 'calculateItems' => $defaultCount);
        }

        $reportItemsOrder = $this->container->get('icsoc_data.model.role')->getReportConfigOrder($newItems, 100);
        foreach ($reportItemsOrder as $item => $reportConfig) {
            $reportConfigs[$item] = array(
                'text' => $reportConfig['name'],
                'field' => $reportConfig['field'],
                'sortable' => false,
                'width' => $reportConfig['width'],
                'default_show' => true,
            );
        }

        return array('configs' => $reportConfigs, 'calculateItems' => $calculateItems);

    }


    /**
     * 处理配置信息
     * @param array $param
     * @return array
     */
    private function processConfig($param)
    {
        $reportName = isset($param['report_name']) ? $param['report_name'] : '';
        $reportType = isset($param['report_type']) ? $param['report_type'] : '';
        $dataType = isset($param['data_type']) ? $param['data_type'] : '';
        $roleId = isset($param['roleId']) ? $param['roleId'] : '';
        $defaultTitle = $this->reportItems[$reportName]['fixed_report'];
        $defaultCount = $this->calculateItems[$reportName];
        $allTitles = $this->reportItems[$reportName]['fixed_report'];

        switch ($reportName) {
            case 'system':
                $connect = array(5, 10, 15, 20, 30);
                $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect);
                $allTitles = $res['title'];
                break;
            case 'queue':
                $connect = array(5, 10, 15, 20, 30);
                $waive = array(10, 20, 25, 30, 35, 40);
                $res = $this->proccessXSecs($defaultTitle, $defaultCount, $connect, $waive);
                $allTitles = $res['title'];
                break;
            case 'agent':
            case 'group':
                $allTitles = $this->proccessStaReason($defaultTitle, $reportType);
                break;
        }

        if (!empty($roleId)) {
            $configs = $this->getReportConfig($reportName, $roleId, 'fixed', $reportType);
            $configTitle = $configs['configs'];
            $allTitles = array_merge($allTitles, $configTitle);
            foreach ($configTitle as $item => $config) {
                if (isset($defaultTitle[$item]['field'])) {
                    $configTitle[$item]['field'] = $defaultTitle[$item]['field'];
                }

                //去除数据库中保存的置忙原因，因为置忙原因可能被修改，而数据库中保存的值还是旧值
                if (strpos($item, 'agstanum') !== false || strpos($item, 'agstaduration') !== false) {
                    unset($configTitle[$item]);
                }

                /** 业务组和坐席半小时报表要去掉坐席状态原因*/
                if (strpos($item, 'agsta') !== false && $reportType == 'halfhour' && ($reportName == 'group' || $reportName == 'agent')) {
                    unset($configTitle[$item]);
                }
            }
            //重新添加新的置忙原因
            if (($reportName == 'agent' || $reportName == 'group') && $reportType != 'halfhour') {
                $configTitle = $this->proccessStaReason($configTitle, $reportType);
            }
            $defaultTitle = $configTitle;
            $defaultCount = $configs['calculateItems'];
            $allTitles = array_merge($allTitles, $defaultTitle);
        }

        $title = $defaultTitle;
        $count = $defaultCount;
        if ($dataType == 'data') {
            $title = array('title' => $defaultTitle, 'count' => $count, 'allTitles' => $allTitles);
        }

        return array('code' => 200, 'message' => 'success', 'data' => $title);
    }

    /**
     * @param $multiplys //计算项的乘法部分包括分子或分母 $item['numerator']['multiply'],每个乘法部分都包括加法或者减法，目前只支持两个指标相乘
     * @return array('multiplyPlusSum' => 'multiplyMinusSum' => )
     */
    public function processMultiplyItems($multiplys, $allTitles, $value, $count)
    {
        $multiplyPlusSum = 0;
        $multiplyMinusSum = 0;
        if (isset($multiplys['plus'])) {
            foreach ($multiplys['plus'] as $multiplyItems) {
                $multiplyPlus = explode('*', $multiplyItems);
                $multiplyPlusFirst = 0;
                $multiplyPlusSecond = 0;
                /** 当乘法配置中只有一个配置项且该配置项在第一个位置，才会计算*/
                if ($multiplyPlus[0] == 'firstMultiplyItem' && count($multiplys['plus']) == 1) {
                    //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                    if (is_numeric($multiplyPlus[1])) {
                        $multiplyPlusSecond = (int) $multiplyPlus[1];
                    } else {
                        if (isset($value[$allTitles[$multiplyPlus[1]]['field']])) {
                            $multiplyPlusSecond = $value[$allTitles[$multiplyPlus[1]]['field']];
                            if (strpos($multiplyPlusSecond, '%')) {
                                $multiplyPlusSecond = floatval($multiplyPlusSecond) / 100;
                            }
                        } else {
                            $multiplyPlusSecond = 0;
                            if (in_array($multiplyPlus[1], array_keys($count))) {
                                $multiplyPlusSecond = $this->simplyCalculate($allTitles, $value, $count[$multiplyPlus[1]]);
                            }
                        }
                    }
                    $multiplyPlusSum += 1*$multiplyPlusSecond;
                } else {
                    //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                    if (is_numeric($multiplyPlus[0])) {
                        $multiplyPlusFirst = (int) $multiplyPlus[0];
                    } else {
                        if (isset($allTitles[$multiplyPlus[0]]['field'])) {
                            if (isset($value[$allTitles[$multiplyPlus[0]]['field']])) {
                                $multiplyPlusFirst = $value[$allTitles[$multiplyPlus[0]]['field']];
                                if (strpos($multiplyPlusFirst, '%')) {
                                    $multiplyPlusFirst = floatval($multiplyPlusFirst) / 100;
                                }
                            } else {//乘数为需要计算的项，即不能直接从value中取到值
                                $multiplyPlusFirst = 0;
                                if (in_array($multiplyPlus[0], array_keys($count))) {
                                    $multiplyPlusFirst = $this->simplyCalculate($allTitles, $value,$count[$multiplyPlus[0]]);
                                }
                            }
                        }
                    }

                    //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                    if (is_numeric($multiplyPlus[1])) {
                        $multiplyPlusSecond = (int) $multiplyPlus[1];
                    } else {
                        if (isset($allTitles[$multiplyPlus[1]]['field'])) {
                            if (isset($value[$allTitles[$multiplyPlus[1]]['field']])) {
                                $multiplyPlusSecond = $value[$allTitles[$multiplyPlus[1]]['field']];
                                if (strpos($multiplyPlusSecond, '%')) {
                                    $multiplyPlusSecond = floatval($multiplyPlusSecond) / 100;
                                }
                            } else {
                                $multiplyPlusSecond = 0;
                                if (in_array($multiplyPlus[1], array_keys($count))) {
                                    $multiplyPlusSecond = $this->simplyCalculate($allTitles, $value, $count[$multiplyPlus[1]]);
                                }
                            }
                        }
                    }

                    $multiplyPlusSum += $multiplyPlusFirst*$multiplyPlusSecond;
                }
            }
        }

        if (isset($multiplys['minus'])) {
            foreach ($multiplys['minus'] as $multiplyItems) {
                $multiplyMinus = explode('*', $multiplyItems);
                $multiplyMinusFirst = 0;
                $multiplyMinusSecond = 0;
                if ($multiplyMinus[0] == 'firstMultiplyItem' && count($multiplys['minus']) == 1) {
                    //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                    if (is_numeric($multiplyMinus[1])) {
                        $multiplyMinusSecond = (int) $multiplyMinus[1];
                    } else {
                        if (isset($value[$allTitles[$multiplyMinus[1]]['field']])) {
                            $multiplyMinusSecond = $value[$allTitles[$multiplyMinus[1]]['field']];
                            if (strpos($multiplyMinusSecond, '%')) {
                                $multiplyMinusSecond = floatval($multiplyMinusSecond) / 100;
                            }
                        } else {
                            if (in_array($multiplyMinus[1], array_keys($count))) {
                                $multiplyMinusSecond = $this->simplyCalculate($allTitles, $value, $count[$multiplyMinus[1]]);
                            }
                        }
                    }
                    $multiplyMinusSum += 1*$multiplyMinusSecond;
                } else {
                    if (is_numeric($multiplyMinus[0])) {
                        $multiplyMinusFirst = (int) $multiplyMinus[0];
                    } else {
                        if (isset($allTitles[$multiplyMinus[0]]['field'])) {
                            if (isset($value[$allTitles[$multiplyMinus[0]]['field']])) {
                                $multiplyMinusFirst = $value[$allTitles[$multiplyMinus[0]]['field']];
                                if (strpos($multiplyMinusFirst, '%')) {
                                    $multiplyMinusFirst = floatval($multiplyMinusFirst) / 100;
                                }
                            } else {
                                $multiplyMinusFirst = 0;
                                if (in_array($multiplyMinus[0], array_keys($count))) {
                                    $multiplyMinusFirst = $this->simplyCalculate($allTitles, $value, $count[$multiplyMinus[0]]);
                                }
                            }
                        }
                    }

                    if (is_numeric($multiplyMinus[1])) {
                        $multiplyMinusSecond = (int) $multiplyMinus[1];
                    } else {
                        if (isset($allTitles[$multiplyMinus[1]]['field'])) {
                            if (isset($value[$allTitles[$multiplyMinus[1]]['field']])) {
                                $multiplyMinusSecond = $value[$allTitles[$multiplyMinus[1]]['field']];
                                if (strpos($multiplyMinusSecond, '%')) {
                                    $multiplyMinusSecond = floatval($multiplyMinusSecond) / 100;
                                }
                            } else {
                                $multiplyMinusSecond = 0;
                                if (in_array($multiplyMinus[1], array_keys($count))) {
                                    $multiplyMinusSecond = $this->simplyCalculate($allTitles, $value, $count[$multiplyMinus[1]]);
                                }
                            }
                        }
                    }

                    $multiplyMinusSum += $multiplyMinusFirst*$multiplyMinusSecond;
                }
            }
        }

        return array('plusSum' => $multiplyPlusSum, 'minusSum' => $multiplyMinusSum);
    }

    /**
     * @param $allTitles
     * @param $value
     * @param $item
     * @return float|int
     */
    public function simplyCalculate($allTitles, $value, $item)
    {
        $divisorPlusSum = 0;
        $divisorMinusSum = 0;
        $dividendPlusSum = 0;
        $dividendMinusSum = 0;

        if (!empty($item['numerator']['multiply'])) {
            $res = $this->processMultiplyItems($item['numerator']['multiply'], $allTitles, $value);
            $divisorPlusSum += $res['plusSum'];
            $divisorMinusSum += $res['minusSum'];
        }

        if (!empty($item['denominator']['multiply'])) {
            $res = $this->processMultiplyItems($item['denominator']['multiply'], $allTitles, $value);
            $dividendPlusSum += $res['plusSum'];
            $dividendMinusSum += $res['minusSum'];
        }

        if (!empty($item['numerator']['plus'])) {
            foreach ($item['numerator']['plus'] as $val) {
                //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                if (is_numeric($val)) {
                    $divisorPlusSum += (int) $val;
                } else {
                    if (!isset($allTitles[$val]['field'])) {
                        continue;
                    }
                    $divisorPlusSum += isset($value[$allTitles[$val]['field']]) ? $value[$allTitles[$val]['field']] : 0;
                }
            }
        }

        if (!empty($item['numerator']['minus'])) {
            foreach ($item['numerator']['minus'] as $val) {
                if (is_numeric($val)) {
                    $divisorMinusSum += (int) $val;
                } else {
                    if (!isset($allTitles[$val]['field'])) {
                        continue;
                    }
                    $divisorMinusSum += isset($value[$allTitles[$val]['field']]) ? $value[$allTitles[$val]['field']] : 0;
                }
            }
        }
        $numerator = $divisorPlusSum - $divisorMinusSum;

        if (!empty($item['denominator']['plus'])) {
            foreach ($item['denominator']['plus'] as $val) {
                if (is_numeric($val)) {
                    $dividendPlusSum += (int) $val;
                } else {
                    if (!isset($allTitles[$val]['field'])) {
                        continue;
                    }
                    $dividendPlusSum += isset($value[$allTitles[$val]['field']]) ? $value[$allTitles[$val]['field']] : 0;
                }
            }
        }
        if (!empty($item['denominator']['minus'])) {
            foreach ($item['denominator']['minus'] as $val) {
                if (is_numeric($val)) {
                    $dividendMinusSum += (int) $val;
                } else {
                    if (!isset($allTitles[$val]['field'])) {
                        continue;
                    }
                    $dividendMinusSum += isset($value[$allTitles[$val]['field']]) ? $value[$allTitles[$val]['field']] : 0;
                }
            }
        }
        $denominator = $dividendPlusSum - $dividendMinusSum;
        $trueValue = $denominator > 0 ? round($numerator / $denominator) : $numerator;

        return $trueValue;
    }

    /**
     * 给value添加计算的字段
     * @param $value
     * @param $count
     * @param $title
     * @param $reportName
     * @return mixed
     */
    private function addCalculationField($value, $count, $title, $reportName, $allTitles)
    {
        foreach ($count as $k => $v) {
            $divisorPlusSum = 0;
            $divisorMinusSum = 0;
            $dividendPlusSum = 0;
            $dividendMinusSum = 0;

            if (!isset($title[$k]['field'])) {
                continue;
            }

            if (!empty($v['numerator']['multiply'])) {
                $res = $this->processMultiplyItems($v['numerator']['multiply'], $allTitles, $value, $count);
                $divisorPlusSum += $res['plusSum'];
                $divisorMinusSum += $res['minusSum'];
            }

            if (!empty($v['denominator']['multiply'])) {
                $res = $this->processMultiplyItems($v['denominator']['multiply'], $allTitles, $value, $count);
                $dividendPlusSum += $res['plusSum'];
                $dividendMinusSum += $res['minusSum'];
            }

            if (!empty($v['numerator']['plus'])) {
                foreach ($v['numerator']['plus'] as $val) {
                    if (is_numeric($val)) {
                        $divisorPlusSum += (int) $val;
                    } else {
                        if (!isset($allTitles[$val]['field'])) {
                            continue;
                        }
                        $nowValue = 0;
                        if (isset($value[$allTitles[$val]['field']])) {
                            if (strpos($value[$allTitles[$val]['field']], '%')) {
                                $nowValue = floatval($value[$allTitles[$val]['field']]) / 100;
                            } else {
                                $nowValue = $value[$allTitles[$val]['field']];
                            }
                        }
                        $divisorPlusSum += isset($value[$allTitles[$val]['field']]) ? $nowValue : 0;
                    }
                }
            }

            if (!empty($v['numerator']['minus'])) {
                foreach ($v['numerator']['minus'] as $val) {
                    if (is_numeric($val)) {
                        $divisorMinusSum += (int) $val;
                    } else {
                        if (!isset($allTitles[$val]['field'])) {
                            continue;
                        }
                        if (isset($value[$allTitles[$val]['field']])) {
                            if (strpos($value[$allTitles[$val]['field']], '%')) {
                                $nowValue = floatval($value[$allTitles[$val]['field']]) / 100;
                            } else {
                                $nowValue = $value[$allTitles[$val]['field']];
                            }
                        }
                        $divisorMinusSum += isset($value[$allTitles[$val]['field']]) ? $nowValue : 0;
                    }
                }
            }
            $numerator = $divisorPlusSum - $divisorMinusSum;

            if (!isset($v['denominator'])) {
                if ($reportName == 'agent' || $reportName == 'group') {
                    $value[$title[$k]['field']] = $numerator;
                    continue;
                }
                $value[$title[$k]['field']] = $numerator > 0 ? $numerator : 0 ;
                continue;
            }

            if (!empty($v['denominator']['plus'])) {
                foreach ($v['denominator']['plus'] as $val) {
                    if (is_numeric($val)) {
                        $dividendPlusSum += (int) $val;
                    } else {
                        if (!isset($allTitles[$val]['field'])) {
                            continue;
                        }
                        if (isset($value[$allTitles[$val]['field']])) {
                            if (strpos($value[$allTitles[$val]['field']], '%')) {
                                $nowValue = floatval($value[$allTitles[$val]['field']]) / 100;
                            } else {
                                $nowValue = $value[$allTitles[$val]['field']];
                            }
                        }
                        $dividendPlusSum += isset($value[$allTitles[$val]['field']]) ? $nowValue : 0;
                    }
                }
            }
            if (!empty($v['denominator']['minus'])) {
                foreach ($v['denominator']['minus'] as $val) {
                    if (is_numeric($val)) {
                        $dividendMinusSum += (int) $val;
                    } else {
                        if (!isset($allTitles[$val]['field'])) {
                            continue;
                        }
                        if (isset($value[$allTitles[$val]['field']])) {
                            if (strpos($value[$allTitles[$val]['field']], '%')) {
                                $nowValue = floatval($value[$allTitles[$val]['field']]) / 100;
                            } else {
                                $nowValue = $value[$allTitles[$val]['field']];
                            }
                        }
                        $dividendMinusSum += isset($value[$allTitles[$val]['field']]) ? $nowValue : 0;
                    }
                }
            }
            $denominator = $dividendPlusSum - $dividendMinusSum;

            if (isset($v['percent']) && $v['percent'] == 1) {
                $value[$title[$k]['field']] = '0%';
                if ($denominator > 0) {
                    $value[$title[$k]['field']] = round($numerator / $denominator * 100, 2);
                    $value[$title[$k]['field']] = $value[$title[$k]['field']] > 100 ?
                        '100%' : $value[$title[$k]['field']].'%';
                }
            } else {
                $value[$title[$k]['field']] = $denominator > 0 ? round($numerator / $denominator) : $numerator;
            }
        }

        return $value;
    }

    /**
     * 处理时间
     * @param $value
     * @param $type
     * @return string
     */
    private function processDate($value, $type, $reportShowType)
    {
        switch ($type) {
            default:
            case 'day':
                return $value['nowdate'];
                break;
            case 'month':
                return $value['start_date'];
                break;
            case 'hour':
                if (!empty($reportShowType) && $reportShowType == 2) {
                    return $value['time_stamp'].'时';
                }
                return $value['start_date'].' '.$value['time_stamp'].'时';
                break;
            case 'halfhour':
                $hour = sprintf("%02d", floor($value['time_stamp']/2)).":";
                $minute = $value['time_stamp']%2 == 1 ? "30" : "00";

                if (!empty($reportShowType) && $reportShowType == 2) {
                    return $hour.$minute;
                }
                return $value['start_date'].' '.$hour.$minute;
                break;
        }
    }

    /**
     * 公共数据处理
     * @param $data
     * @param $vccId
     * @param $repType
     * @param $type
     * @return array
     */
    private function processData($data, $vccId, $repType, $type, $roleId, $reportShowType, $footer = false)
    {
        /** @var  $configs (工作量小时、天) */
        $configs = $this->container->get("doctrine.dbal.default_connection")->fetchAssoc(
            "SELECT work_day,work_hour,conn_num,lost_num
            FROM cc_ccod_configs
            WHERE vcc_id = $vccId"
        );

        $workDay  = empty($configs['work_day'])  ? 30 : $configs['work_day'];
        $workHour = empty($configs['work_hour']) ? 24 : $configs['work_hour'];
        switch($repType) {
            case 'month':
                $workTime = $workDay*$workHour*3600;
                break;
            case 'day':
                $workTime = $workHour*3600;
                break;
            case 'hour':
                $workTime = 3600;
                break;
            case 'halfhour':
                $workTime = 1800;
                break;
            default:
                $workTime = 3600;
                break;
        }
        $param = array(
            'data' => $data,
            'report_name' => $type,
            'work_time' => $workTime,
            'rep_type' => $repType,
            'roleId' => $roleId,
            'reportShowType' => $reportShowType,
            'footer' => $footer,
        );
        $gridData = array();
        $footer = array();
        $rst = $this->getDataReport($param);
        if (isset($rst['code']) && $rst['code'] == 200) {
            $gridData = $rst['data'];
            $footer = $rst['footer'];
        }

        return array('data' => $gridData, 'footer' => $footer);
    }

    /**
     * 给每条数据处理相关字段；
     * @param $value
     * @param $type
     * @return mixed
     */
    private function proccessValue($value, $type)
    {
        $conn =  $this->container->get('doctrine.dbal.default_connection');
        switch ($type) {
            case 'system':
                break;
            case 'queue':
                if (isset($value['que_id'])) {
                    $queName= $conn->fetchColumn(
                        "SELECT que_name FROM win_queue WHERE id = ?",
                        array($value['que_id'])
                    );
                    $value['queue_name'] = empty($queName) ? '' : $queName;
                }
                break;
            case 'agent':
                break;
            case 'group':
                if (isset($value['group_id'])) {
                    $groupName = $conn->fetchColumn(
                        "SELECT group_name FROM win_group WHERE group_id = ?",
                        array($value['group_id'])
                    );
                    $value['group_name'] = empty($groupName) ? '' : $groupName;
                }
                break;
        }

        return $value;
    }

    /**
     * 处理X秒的字段
     * @param $defaultTitle
     * @param $defaultCount
     * @param array $connect
     * @param array $waive
     * @return mixed
     */
    private function proccessXSecs($defaultTitle, $defaultCount, $connect = array(), $waive = array())
    {
        foreach ($connect as $v) {
            $defaultTitle['conn'.$v.'_num'] = array(
                'text' => sprintf('%s秒接通量', $v),
                'field' => 'conn'.$v.'_num',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            );
            $defaultTitle['conn'.$v.'_rate'] = array(
                'text' => sprintf('%s秒接通率', $v),
                'field' =>'conn'.$v.'_rate',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            );
            $defaultCount['conn'.$v.'_rate'] = array(
                'numerator' => array(
                    'plus' => array('conn'.$v.'_num'),
                ),
                'denominator' => array(
                    'plus' => array('inboundConnNum'),
                ),
                'percent' => 1,
            );
        }

        foreach ($waive as $v) {
            $defaultTitle['lost'.$v.'_num'] = array(
                'text' => sprintf('%s秒放弃量', $v),
                'field' =>'lost'.$v.'_num',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            );
            $defaultTitle['lost'.$v.'_rate'] = array(
                'text' => sprintf('%s秒放弃率', $v),
                'field' =>'lost'.$v.'_rate',
                'sortable' => true,
                'width' => 110,
                'default_show' => true,
            );
            $defaultCount['lost'.$v.'_rate'] = array(
                'numerator' => array(
                    'plus' => array('lost'.$v.'_num'),
                ),
                'denominator' => array(
                    'plus' => array('inboundAbandonTotalNum'),
                ),
                'percent' => 1,
            );
        }

        return array('title' => $defaultTitle, 'count' => $defaultCount);
    }

    /**
     * 处理置忙原因字段
     * @param $defaultTitle
     * @param $reportType
     * @return mixed
     */
    public function proccessStaReason($defaultTitle, $reportType)
    {
        if ($reportType != 'halfhour') {
            $user = $this->container->get('security.token_storage')->getToken()->getUser();
            $vccId = $user->getVccId();
            $agentStaReason = $this->container->get('icsoc_data.model.report')
                ->getAgentStaReason($vccId);
            foreach ($agentStaReason as $key => $v) {
                $defaultTitle['agstanum'.$key] = array(
                    'text' => $v.'次数',
                    'field' => 'agstanum'.$key,
                    'sortable' => false,
                    'width' => 110,
                    'default_show' => true,
                );
                if ($reportType == 'day' || $reportType == 'month') {
                    $defaultTitle['agstaduration'.$key] = array(
                        'text' => $v.'时长',
                        'field' => 'agstaduration'.$key,
                        'sortable' => false,
                        'width' => 110,
                        'default_show' => true,
                    );
                }
            }
            if (!empty($agentStaReason)) {
                $defaultTitle['agstanum_other'] = array(
                    'text' => '其他置忙次数',
                    'field' => 'agstanum_other',
                    'sortable' => false,
                    'width' => 110,
                    'default_show' => true,
                );
                if ($reportType == 'day' || $reportType == 'month') {
                    $defaultTitle['agstaduration_other'] = array(
                        'text' => '其他置忙时长',
                        'field' => 'agstaduration_other',
                        'sortable' => false,
                        'width' => 110,
                        'default_show' => true,
                    );
                }
            }
        }

        return $defaultTitle;
    }
}
